package top.lyc829.mymusic.model.http

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import top.lyc829.mymusic.model.bean.LoginParam
import top.lyc829.mymusic.model.bean.PlayListResult
import top.lyc829.mymusic.model.http.api.*
import top.lyc829.mymusic.util.Const
import java.lang.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

/**
 * @Author lyc
 * @create 2021-06-29 00:53
 */
class MyNetwork {

    private val authService = ServiceCreator.create<AuthService>()
    private val indexService = ServiceCreator.create<IndexService>()
    private val playListService = ServiceCreator.create<PlayListService>()
    private val songService = ServiceCreator.create<SongService>()
    private val commentService = ServiceCreator.create<CommentService>()

    suspend fun login(param: LoginParam) = authService.login(param)

    suspend fun getBanners(type : Int) = indexService.getBanners(type)

    suspend fun search(keywords : String) = indexService.search(keywords).await()

    suspend fun getIndexRecommendPlayList() = indexService.getIndexRecommendPlayList()

    suspend fun getPlayListDetail(id: Long) = playListService.getPlaylistDetail(id)

    suspend fun getSongs(ids: String) = songService.getSongs(ids)
    suspend fun getSongsUrl(id: String) = songService.getSongsUrl(id)

    suspend fun getTopAlbums() = indexService.getTopAlbums(3)
    suspend fun getNewSongs() = indexService.getIndexNewSongs(7)

    suspend fun getTopPlayList(offset: Int = 0, limit: Int = 50, order: String = Const.HOT, cat: String = Const.CATEGORY_ALL) = playListService.getTopPlayList(offset, limit, order, cat)

    /**
     * 评论
     */
    suspend fun getPlayListComments(id: Long, limit: Int = 20, offset: Int = 0) = commentService.getPlayListComments(id, limit, offset)


    private suspend fun <T> Call<T>.await(): T {
        return suspendCoroutine {
            enqueue(object : Callback<T> {
                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if (body != null) it.resume(body)
                    else it.resumeWithException(RuntimeException("response is null"))
                }

                override fun onFailure(call: Call<T>, t: Throwable) {
                    it.resumeWithException(t)
                }

            })
        }
    }

    companion object {

        private var network: MyNetwork? = null

        fun getInstance(): MyNetwork {
            if (network == null) {
                synchronized(MyNetwork::class.java) {
                    if (network == null) {
                        network = MyNetwork()
                    }
                }
            }
            return network!!
        }

    }


}